#include "app.h" 

#define ADC_BUF_SIZE 16
int AdcBuf[8][ADC_BUF_SIZE + 1] = {0} ;


// 任务
MultiTask mTask1  , mTask2  , mTask3 , mTask4 , mTask5 ;

int ledpin=13;//指定LED端口 13
int pwmpin = 3;

int mEvalOky = 0 ; //纸飞机自动上送
float evalBuf[15] ;
int serial_putc( char c, struct __file * );
void printf_begin(void);

/**
 * @brief 初始化
 * 
 */
void App_Init()  {
    printf_begin();
    Serial.begin(115200,SERIAL_8N1);//设置串口波特率为115200
    while (!Serial) ;
    pinMode(ledpin,OUTPUT);//设置端口13为输出模式
    // pinMode(pwmpin,OUTPUT);//3 5 

    // EEPROM.write(0,12);  //nano 1K EEPROM 
    // LOG("EEPROM:%d",EEPROM.read(0));

    //定时任务
#if (ENABLE_MULTITASK )
    MultiTaskStart(&mTask1, 500, mTask1_cb, (void *)0); // LED指示灯任务 
    MultiTaskStart(&mTask2, 1 , mTask2_cb, (void *)0); // 解析串口指令任务 
    // MultiTaskStart(&mTask3, 100 , mTask3_cb, (void *)0); // 纸飞机数据绘图
     MultiTaskStart(&mTask4, 100 , mTask4_cb, (void *)0) ; // 
     MultiTaskStart(&mTask5, 10 , mTask5_cb, (void *)0) ;  // 读取温度
#endif 

}

/*------------------- Task ------------------*/
/**
 * @brief LED指示灯任务
 * 
 * @param task 
 * @param userData 
 */
void mTask1_cb(MultiTask* task, void *userData)
{
    static uint8_t ttl= 0 ;
    digitalWrite(ledpin,(ttl++)&0x1);//拉高端口13，LED点亮
}

/**
 * @brief 串口指令解析
 * 
 * @param task 
 * @param userData 
 */
#define ANALOG_PIN(n) A##n
void mTask2_cb(MultiTask* task, void *userData)
{
    static unsigned long cfifo ;
    int c ; 
    while(Serial.available() > 0)
	{
        c =  char(Serial.read())&0xff ;
        // 读入数据
		cfifo =((cfifo<<8) |  c) & 0xffffff ;
        //解码
        if(cfifo == 0xFA01FF) {
            LOG_Printf("=============================\r\n");
            LOG_Printf("CH0: %d \r\n",AdcBuf[0][0]);
            LOG_Printf("CH1: %d \r\n",AdcBuf[1][0]);
            LOG_Printf("CH2: %d \r\n",AdcBuf[2][0]);
            LOG_Printf("CH3: %d \r\n",AdcBuf[3][0]);
            LOG_Printf("CH4: %d \r\n",AdcBuf[4][0]);
            LOG_Printf("CH5: %d \r\n",AdcBuf[5][0]);
            LOG_Printf("CH6: %d \r\n",AdcBuf[6][0]);
            LOG_Printf("CH7: %d \r\n",AdcBuf[7][0]);
            LOG_Printf("\r\n");
        }

        // 按行上送
        if(cfifo == 0xFA02FF) { 
            LOG_Printf("%04d %04d %04d %04d %04d %04d %04d %04d \r\n",
                AdcBuf[0][0],
                AdcBuf[1][0],
                AdcBuf[2][0],
                AdcBuf[3][0],
                AdcBuf[4][0],
                AdcBuf[5][0],
                AdcBuf[6][0],
                AdcBuf[7][0] 
            );
        }
        // 纸飞机浮点数上送ADC
        if((cfifo & 0xff0000) == 0xFB0000) {
            MultiTaskCnt_t t = cfifo & 0xffff ;
            if(t==0) MultiTaskStop(&mTask3) ;
            else MultiTaskStart(&mTask3, t , mTask3_cb, (void *)0); // 纸飞机数据绘图
        }

        // 字符串形式上送
        if((cfifo & 0xff0000) == 0xFC0000) {
            MultiTaskCnt_t t = cfifo & 0xffff ;
            if(t==0) MultiTaskStop(&mTask4) ;
            else MultiTaskStart(&mTask4, t , mTask4_cb, (void *)0); // 纸飞机数据绘图
        }

        // 纸飞机浮点数上送换算的温度值
        if((cfifo & 0xff0000) == 0xFd0000) {
            MultiTaskCnt_t t = cfifo & 0xffff ;
            if(t==0) MultiTaskStop(&mTask5) ;
            else MultiTaskStart(&mTask5, t , mTask5_cb, (void *)0); // 纸飞机数据绘图
        }
        
    }

} 


/**
 * @brief 纸飞机浮点数绘图任务
 * 
 * @param task 
 * @param userData 
 */
void mTask3_cb(MultiTask* task, void *userData)
{
    evalBuf[0] = AdcBuf[0][0];
    evalBuf[1] = AdcBuf[1][0];
    evalBuf[2] = AdcBuf[2][0];
    evalBuf[3] = AdcBuf[3][0];
    evalBuf[4] = AdcBuf[4][0];
    evalBuf[5] = AdcBuf[5][0];
    evalBuf[6] = AdcBuf[6][0];
    evalBuf[7] = AdcBuf[7][0];
    EVAL_Line(evalBuf,8);
}

/**
 * @brief 自动连续上送文本数据任务
 * 
 * @param task 
 * @param userData 
 */
void mTask4_cb(MultiTask* task, void *userData)
{
    LOG_Printf("%04d %04d %04d %04d %04d %04d %04d %04d \r\n",
                AdcBuf[0][0],
                AdcBuf[1][0],
                AdcBuf[2][0],
                AdcBuf[3][0],
                AdcBuf[4][0],
                AdcBuf[5][0],
                AdcBuf[6][0],
                AdcBuf[7][0] 
            );
}


/**
 * @brief 自动连续上送采集的温度数据到纸飞机
 * 
 * @param task 
 * @param userData 
 */


void mTask5_cb(MultiTask* task, void *userData)
{
    for(int i=0;i<8;++i) {
    	uint8_t  addr = A0 + i;
        int sum = 0 ;
    	for(int j=1;j<ADC_BUF_SIZE;++j) {
    		AdcBuf[i][j] = AdcBuf[i][j+1] ;
            sum += AdcBuf[i][j] ;
    	}
        AdcBuf[i][ADC_BUF_SIZE] = analogRead(addr);
        sum += AdcBuf[i][ADC_BUF_SIZE] ;
        AdcBuf[i][0] = sum / ADC_BUF_SIZE ;
    }


    // evalBuf[0] = Get_temper( (AdcBuf[0) + AdcBuf[0) + AdcBuf[0) +AdcBuf[0))/4  );
    // evalBuf[1] = Get_temper( (AdcBuf[1) + AdcBuf[1) + AdcBuf[1) +AdcBuf[1))/4  );
    // evalBuf[2] = Get_temper( (AdcBuf[2) + AdcBuf[2) + AdcBuf[2) +AdcBuf[2))/4  );
    // evalBuf[3] = Get_temper( (AdcBuf[3) + AdcBuf[3) + AdcBuf[3) +AdcBuf[3))/4  );
    // evalBuf[4] = Get_temper( (AdcBuf[4) + AdcBuf[4) + AdcBuf[4) +AdcBuf[4))/4  );
    // evalBuf[5] = Get_temper( (AdcBuf[5) + AdcBuf[5) + AdcBuf[5) +AdcBuf[5))/4  );
    // evalBuf[6] = Get_temper( (AdcBuf[6) + AdcBuf[6) + AdcBuf[6) +AdcBuf[6))/4  );
    // evalBuf[7] = Get_temper( (AdcBuf[7) + AdcBuf[7) + AdcBuf[7) +AdcBuf[7))/4  );
    // EVAL_Line(evalBuf,8);
}


/**
 * @brief 纸飞机串口助手绘图
 * 
 * @param dwTemp 
 * @param size 
 */
void EVAL_Line(float *dwTemp , uint8_t size) {
	for(int i=0;i<size; i++) {
		Serial.write((*(char *)(&dwTemp[i])) )  ;
		Serial.write((*((char *)(&dwTemp[i]) + 1)))  ;
		Serial.write((*((char *)(&dwTemp[i]) + 2)) )  ;
		Serial.write((*((char *)(&dwTemp[i]) + 3)))  ;
	}
	Serial.write(0x00)  ;
	Serial.write(0x00)  ;
	Serial.write(0x80)  ;
	Serial.write(0x7F)  ;
};



/**
 * @brief 定时 ms 
 * 
 * @param ms 
 * @return uint8_t 
 */
uint8_t isMsOky(unsigned long ms) {
    static unsigned long oms = 0 ; 
    uint8_t rt = 0 ;
    if(millis() - oms  >= ms) rt = 1 ; 
    oms = millis() ;

    // if(timer0_millis - oms  >= ms) rt = 1 ; 
    // oms = timer0_millis;
    
    return rt ; 
}




// ------------ 
int serial_putc( char c, struct __file * )
{
    Serial.write( c );
    return c;
}
void printf_begin(void)
{
    fdevopen( &serial_putc, 0 );
}
